package com.example.thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SingleThreadedExcutionPattern_Runnable2 {

    public static void main(String[] args){
        System.out.println("Testing Gate.");
        Lock lock = new ReentrantLock();
        Gate gate = new Gate(lock);
        UserRunnable userRunnable = new UserRunnable();
        userRunnable.setUserRunnable(gate,"Alice","Alaska");
        new Thread(userRunnable).start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        UserRunnable userRunnable1 = new UserRunnable();
        userRunnable1.setUserRunnable(gate,"Bobby","Brazil");
        new Thread(userRunnable1).start();
//        userRunnable.setUserRunnable(gate,"Chris","Canada");
//        new Thread(userRunnable).start();



        new TestUserThread(gate).start();
    }

    static class TestUserThread extends Thread{
        private final Gate gate;
        TestUserThread(Gate gate){
            this.gate = gate;
        }

        @Override
        public void run() {
            while(true){
                System.out.println(gate.toString());
            }
        }
    }

    static class UserRunnable implements Runnable{
        private  Gate gate;
        private  String myname;
        private  String myaddress;

        public void setUserRunnable(Gate gate, String myname, String myaddress) {
            this.gate = gate;
            this.myname = myname;
            this.myaddress = myaddress;
        }

        @Override
        public void run() {
            System.out.println(myname + " BEGIN");
            while(true){
                gate.pass(myname,myaddress);
            }
        }
    }


    static class Gate{
        private int counter = 0;
        private String name = "Nobody";
        private String address = "Nowhere";
        private Lock lock;

        Gate(Lock lock){
            this.lock = lock;
        }

        public synchronized  void  pass(String name, String address) {

                    this.counter++;
                    this.name = name;
                    try {
                        Thread.sleep(10);

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    this.address = address;
                    //
                    check();

        }

        public synchronized String toString(){
            String temp = name;
            try {
                Thread.sleep(100);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "No." + counter + ":" + temp + "," + address;
        }

        public void  check(){
            if(name.charAt(0) != address.charAt(0)){
                System.out.println("*******BOKEN*****" + toString());
            }
            else {
                System.out.println(toString());
            }
        }
    }
}
